<template>
  <!-- <el-dialog :title="title" :visible.sync="dialogVisible" width="500px" @close="close('ruleForm')"> -->
  <el-form
    class="dialog-form"
    ref="ruleForm"
    :label-position="position"
    :model="ruleForm"
    :label-width="labelWidth || 'auto'"
  >
    <el-row :gutter="20">
      <el-col
        :span="item.span || 24"
        v-for="(item, index) in options"
        :key="'form_' + index"
      >
        <el-form-item
          :label="item.title"
          :prop="item.field"
          :rules="item.rules"
          label-position="top"
        >
          <slot
            :name="item.slot"
            v-if="item.hasOwnProperty('slot') && item.slot"
            :slotProps="item"
          ></slot>
          <template v-else>
            <!-- el-input -->
            <template v-if="item.type === 'input'">
              <span v-if="['view'].includes(mode)">{{
                ruleForm[item.field]
              }}</span>
              <el-input
                v-else
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                type="text"
                :size="item.size || 'small'"
                :maxlength="item.maxlength"
                :show-word-limit="item.showWordLimit || false"
                :disabled="item.disabled || false"
                :readonly="false || false"
                :style="{ width: item.width + 'px' }"
                @blur="(e) => handleChange(item.field, 'input', e)"
              ></el-input>
            </template>

            <!-- el-input-number -->
            <template v-else-if="item.type === 'input-number'">
              <span v-if="['view'].includes(mode)">{{
                ruleForm[item.field]
              }}</span>
              <el-input-number
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                :size="item.size || 'middle'"
                :controls="item.controls"
                :min="item.min"
                :max="item.max"
                :step="item.step"
                :precision="item.precision"
                :disabled="item.disabled || false"
                :readonly="false || false"
                :style="{ width: item.width + 'px' }"
                @blur="(e) => handleChange(item.field, 'number', e)"
              ></el-input-number>
            </template>
            <!-- el-select -->
            <template v-else-if="item.type === 'select'">
              <span v-if="['view'].includes(mode)">{{
                item.options
                  ? item.options.find(
                      (ii) =>
                        ii[item.optionValue || "value"] == ruleForm[item.field]
                    )[item.optionKey || "label"]
                  : ""
              }}</span>
              <el-select
                v-else
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                :size="item.size || 'middle'"
                :disabled="item.disabled || false"
                :readonly="false || false"
                :style="{ width: item.width + 'px' }"
                @change="(e) => handleChange(item.field, 'select', e)"
              >
                <el-option
                  :label="row[item.optionKey] || row.label"
                  :value="row[item.optionValue] || row.value"
                  v-for="row in item.options"
                  :key="row[item.optionValue]"
                ></el-option>
              </el-select>
            </template>

            <template v-else-if="item.type === 'cascader'">
              <span v-if="['view'].includes(mode)">{{
                item.labels
                  ? item.labels.map((ii) => ruleForm[ii]).join(item.separator)
                  : ""
              }}</span>
              <el-cascader
                v-else
                :options="item.options"
                :props="item.props"
                clearable
                :size="item.size || 'middle'"
                :placeholder="item.placeholder"
                :disabled="item.disabled || false"
                :show-all-levels="item.showAllLevels"
                :separator="item.separator"
                v-model="ruleForm[item.field]"
                @change="(e) => handleChange(item.field, 'cascader', e)"
              ></el-cascader>
            </template>

            <!-- el-date-picker -->
            <template v-else-if="item.type === 'date'">
              <span v-if="['view'].includes(mode)">{{
                ruleForm[item.field]
              }}</span>
              <el-date-picker
                v-else
                :type="item.dateType"
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                :range-separator="item.rangeSeparator"
                :size="item.size || 'middle'"
                :disabled="item.disabled || false"
                :readonly="false || false"
                :style="{ width: item.width + 'px' }"
                :format="item.format || 'yyyy-MM-DD '"
                :value-format="item.format || 'yyyy-MM-DD '"
                @change="(e) => handleChange(item.field, 'date', e)"
              ></el-date-picker>
            </template>

            <!-- el-time-picker -->
            <template v-else-if="item.type === 'time'">
              <span v-if="['view'].includes(mode)">{{
                ruleForm[item.field]
              }}</span>
              <el-time-picker
                v-else
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                :size="item.size || 'middle'"
                :disabled="item.disabled || false"
                :readonly="false || false"
                :style="{ width: item.width + 'px' }"
                :format="item.format || 'hh:mm:ss'"
                :value-format="item.format || 'hh:mm:ss'"
                @change="(e) => handleChange(item.field, 'time', e)"
              ></el-time-picker>
            </template>

            <!-- el-switch -->
            <template v-else-if="item.type === 'switch'">
              <span v-if="['view'].includes(mode)">{{
                ruleForm[item.field] === item.activeValue
                  ? item.activeText || "开启"
                  : item.inactiveText || "关闭"
              }}</span>
              <el-switch
                v-else
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                :disabled="item.disabled || false"
                :active-text="item.activeText"
                :inactive-text="item.inactiveText"
                :active-value="item.activeValue"
                :inactive-value="item.inactiveValue"
                :active-color="item.activeColor"
                :inactive-color="item.inactiveColor"
                :validate-event="true"
                @change="(e) => handleChange(item.field, 'switch', e)"
              ></el-switch>
            </template>

            <!-- el-checkbox -->
            <template v-else-if="item.type === 'checkbox'">
              <span v-if="['view'].includes(mode)">{{
                item.options
                  ? item.options
                      .map((ii) =>
                        ii[item.optionValue || "value"] === ruleForm[item.field]
                          ? ii[item.optionKey || "label"]
                          : ""
                      )
                      .join("/")
                  : ""
              }}</span>
              <el-checkbox-group
                v-else
                v-model="ruleForm[item.field]"
                clearable
                :disabled="item.disabled || false"
                @change="(e) => handleChange(item.field, 'checkbox', e)"
              >
                <el-checkbox
                  v-for="row in item.options"
                  :key="row[item.optionValue || 'value']"
                  :label="row[item.optionValue || 'value']"
                  :name="row[item.optionValue || 'value']"
                  >{{ row[item.optionLabel || "label"] }}</el-checkbox
                >
              </el-checkbox-group>
            </template>

            <!-- el-radio -->
            <template v-else-if="item.type === 'radio'">
              <span v-if="['view'].includes(mode)">{{
                item.options
                  ? item.options.find(
                      (ii) =>
                        ii[item.optionValue || "value"] === ruleForm[item.field]
                    )[item.optionKey || "label"]
                  : ""
              }}</span>

              <el-radio-group
                v-else
                v-model="ruleForm[item.field]"
                :disabled="item.disabled || false"
                @change="(e) => handleChange(item.field, 'radio', e)"
              >
                <el-radio
                  v-for="row in item.options"
                  :key="row[item.optionValue || 'value']"
                  :label="row[item.optionValue || 'value']"
                  >{{ row[item.optionKey || "label"] }}</el-radio
                >
              </el-radio-group>
            </template>

            <!-- el-textarea -->
            <template v-else-if="item.type === 'textarea'">
              <span v-if="['view'].includes(mode)">{{
                ruleForm[item.field]
              }}</span>
              <el-input
                v-else
                v-model="ruleForm[item.field]"
                clearable
                :placeholder="item.placeholder"
                type="textarea"
                :maxlength="item.maxlength"
                :disabled="item.disabled || false"
                :readonly="false || false"
                :rows="item.rows"
                :style="{ width: item.width + 'px' }"
                @blur="(e) => handleChange(item.field, 'textarea', e)"
              ></el-input>
            </template>

            <!-- el-upload -->
            <template v-else-if="item.type === 'upload'">
              <TheUpload
                :disabled="item.disabled || mode == 'view'"
                :files="ruleForm[item.field]"
                :limit="item.maxlength"
                @upload="
                  (e) =>
                    (ruleForm[item.field] = e.files.map((file) => file.url))
                "
                :accept="item.accept||'.jpg,.png,.jpeg,.mp4,.mp3'"
              />
            </template>
          </template>
        </el-form-item>
      </el-col>
    </el-row>

    <el-form-item>
      <el-button @click="resetForm('ruleForm')" v-if="mode !== 'view'"
        >重 置</el-button
      >
      <el-button
        type="primary"
        @click="submitForm('ruleForm')"
        v-if="mode !== 'view'"
        >确 定</el-button
      >
      <el-button type="primary" @click="close" v-if="mode === 'view'"
        >关 闭</el-button
      >
    </el-form-item>
  </el-form>

  <!-- </el-dialog> -->
</template>

<script>
import TheUpload from "@/components/TheUpload";
export default {
  components: { TheUpload },
  props: {
    labelWidth: {
      type: String,
      default: "100px",
    },
    position: {
      type: String,
      default: "left",
    },
    mode: {
      type: String,
      default: "create",
    },
    title: {
      type: String,
      default: "123",
    },
    options: {
      type: Array,
      default: () => [
        {
          type: "upload",
          prop: "upload",
          title: "upload",
          default: [
            {
              url: "https://hqmimage.oss-cn-beijing.aliyuncs.com/b930c622947940de9fc007dbe6028543.jpg",
            },
          ],
          disabled: false,
          maxlength: 12,
        },
        {
          type: "input",
          prop: "input",
          title: "ElInput",
          placeholder: "ElInput",
          default: "input",
          size: "large",
          maxlength: 12,
          disabled: false,
          readonly: false,
          width: 270,
          slot: "slotName", //自定义组件插槽名，覆盖默认组件
        },
        {
          type: "input-number",
          prop: "input1",
          title: "ElInput-number",
          placeholder: "ElInput-number",
          default: 1,
          size: "large",
          max: 1,
          min: 0,
          step: 1,
          precision: 2,
          controls: false,
          disabled: false,
          readonly: false,
          width: 270,
        },
        {
          type: "select",
          prop: "select",
          title: "ElSelect",
          placeholder: "ElSelect",
          default: "ElSelect",
          size: "large",
          options: [],
          optionKey: "label",
          optionValue: "value",
          disabled: false,
          readonly: false,
          width: 270,
        },
        {
          type: "date",
          prop: "date",
          title: "date",
          placeholder: "date",
          default: "",
          size: "large",
          disabled: false,
          width: 270,
        },
        {
          type: "time",
          prop: "time",
          title: "time",
          placeholder: "time",
          default: "",
          size: "large",
          disabled: false,
          width: 270,
        },
        // {
        //   type: "checkbox",
        //   prop: "checkbox",
        //   title: "checkbox",
        //   default: [1],
        //   options: [{ label: 1, value: 1 }],
        //   optionKey: "label",
        //   optionValue: "q11",
        //   disabled: false,
        //   width: 270
        // },
        {
          type: "radio",
          prop: "radio",
          title: "radio",
          default: 1,
          options: [{ label: 1, value: 1 }],
          optionKey: "label",
          optionValue: "value",
          disabled: false,
          width: 270,
        },

        {
          type: "textarea",
          prop: "textarea",
          title: "ElInput",
          placeholder: "ElInput",
          default: "input",
          size: "large",
          maxlength: 1,
          disabled: false,
          readonly: false,
          width: 270,
        },
      ],
    },
    form: {
      type: Object,
      default: () => {},
    },
    api: {
      type: Function,
      default: () => {
        return () => {};
      },
    },
    renderFunc: {
      //特殊接口返回数据返回格式化，配合autoPlay：false 使用
      type: Function,
      default: null,
    },
  },
  watch: {
    ruleForm: {
      deep: true,
      immediate: true,
      handler: function (newV, oldV) {
        console.log(newV, "this");
        this.$emit("update:form", newV);
      },
    },
  },
  data() {
    return {
      dialogVisible: true,
      ruleForm: {},
    };
  },
  created() {},
  mounted() {
    this.init();
    console.log(this.form, "ale");
  },
  methods: {
    submitForm(formName) {
      console.log(this.form, "submitForm");
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert("submit!");
          this.$emit("submit", this.ruleForm);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    close(formName) {
      this.$refs[formName].resetFields();
      this.dialogVisible = false;
    },
    handleChange(prop, type, e) {},
    async init() {
      for (let i = 0; i < this.options.length; i++) {
        const item = this.options[i];
        if (this.ruleForm.hasOwnProperty(item.field)) {
          throw "form表单prop[" + item.field + "]字段重复";
        }
        this.$set(this.ruleForm, this.options[i].field, "");
        if (
          Object.prototype.hasOwnProperty.call(item, "default") &&
          item.default !== ""
        ) {
          this.$set(
            this.ruleForm,
            this.options[i].field,
            this.options[i].default
          );
        }
        if (
          Object.prototype.hasOwnProperty.call(item, "api") &&
          item.api !== ""
        ) {
          const api = item.api;
          await api({ ...item.params }).then((res) => {
            if (res.code === 0) {
              item.options = res.data;
            }
          });
        }
      }
    },
    async open(row) {
      const res = await this.api(row);
      if (this.renderFunc) {
        const result = this.renderFunc(res);
        this.ruleForm = { ...result };
      } else {
        if (this.mode === "view") {
          this.ruleForm = res.data;
        } else {
          for (const key in this.ruleForm) {
            if (Object.hasOwnProperty.call(this.ruleForm, key)) {
              this.$set(
                this.ruleForm,
                key,
                res.data[key] || this.ruleForm[key]
              );
            }
          }
        }
      }
      this.dialogVisible = true;
    },
  },
};
</script>
<style lang="scss" scoped>
.dialog-form {
  .el-form-item {
    margin-bottom: 10px;
  }
  ::v-deep .el-form-item__label {
    padding-bottom: 0px !important;
  }
}
</style>
